package com.turman.plyopengl

import android.content.Context
import android.graphics.PointF
import android.opengl.GLSurfaceView
import android.util.AttributeSet
import android.view.MotionEvent
import kotlin.math.sqrt

class BaseGLSurfaceView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
    GLSurfaceView(context, attrs) {
    companion object {
        private const val TOUCH_NONE = 0
        private const val TOUCH_ROTATE = 1
        private const val TOUCH_ZOOM = 2
    }

    private var plyRenderer: PlyRenderer

    private var down_x = -1f
    private var down_y = -1f
    private var down_time = 0L
    private var touchMode = TOUCH_NONE
    private var pinchStartDistance = 0.0f
    private val pinchStartPoint = PointF()
    private var downStartPoint:PointF?=null

    init {
        setEGLContextClientVersion(2)
        plyRenderer = PlyRenderer(context)
        setRenderer(plyRenderer)
    }


    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action and MotionEvent.ACTION_MASK) {
            MotionEvent.ACTION_DOWN -> {
                down_x = event.x
                down_y = event.y
                down_time = System.currentTimeMillis()
            }

            MotionEvent.ACTION_MOVE -> {
                if (downStartPoint==null) {
                    downStartPoint= PointF()
                    downStartPoint?.x = event.x
                    downStartPoint?.y = event.y
                    return true
                }

                if (event.pointerCount == 1) {//单指旋转
                    if (touchMode != TOUCH_ROTATE) {
                        downStartPoint?.x = event.x
                        downStartPoint?.y = event.y
                    }
                    touchMode = TOUCH_ROTATE
                    val x = event.x
                    val y = event.y
                    val dx = x - downStartPoint?.x!!
                    val dy = y - downStartPoint?.y!!
                    if (sqrt(dx*dx+dy*dy)>0.5f) {
                        downStartPoint?.x = x
                        downStartPoint?.y = y
                        plyRenderer.rotate(context.pxToDp(dx), context.pxToDp(dy))
                    }
                } else if (event.pointerCount == 2) {//双指缩放
                    if (touchMode != TOUCH_ZOOM) {
                        pinchStartDistance = getPinchDistance(event)
                        getPinchCenterPoint(event, pinchStartPoint)
                        downStartPoint?.x = pinchStartPoint.x
                        downStartPoint?.y = pinchStartPoint.y
                        touchMode = TOUCH_ZOOM
                    } else {
                        val pt = PointF()
                        getPinchCenterPoint(event, pt)
                        val dx = pt.x - downStartPoint?.x!!
                        val dy = pt.y - downStartPoint?.y!!
                        if (sqrt(dx*dx+dy*dy)>1f) {
                            downStartPoint?.x = pt.x
                            downStartPoint?.y = pt.y
                            val pinchScale = getPinchDistance(event) / pinchStartDistance
                            pinchStartDistance = getPinchDistance(event)
                            plyRenderer.translate(context.pxToDp(dx), context.pxToDp(dy), pinchScale)
                        }
                    }
                }
            }

            MotionEvent.ACTION_UP -> {
                downStartPoint=null
                down_x = -1f
                down_y = -1f
            }
        }
        return true
    }

    private fun getPinchDistance(event: MotionEvent): Float {
        val x = event.getX(0) - event.getX(1)
        val y = event.getY(0) - event.getY(1)
        return sqrt((x * x + y * y).toDouble()).toFloat()
    }

    private fun getPinchCenterPoint(event: MotionEvent, pt: PointF) {
        pt.x = (event.getX(0) + event.getX(1)) * 0.5f
        pt.y = (event.getY(0) + event.getY(1)) * 0.5f
    }
}

























